<?php
namespace app\api\controller;

use app\common\controller\Api;
use app\api\model\Esapi as EsapiModel;
use app\api\model\Standard;
use app\api\controller\KbxOther as KbxOtherController;
use think\Cache;

class Esapi extends Api
{
    public $api_url = 'http://127.0.0.1:9200';
    public $indexArr = ['goods_test','trip_test','product_test','poi_test','faq_test','standard_test'];
    public $otherIndexArr = ['goods','trip','product','poi','faq','standard'];
    public $thirdIndexArr = ['.kibana','read_me'];
    public $send_email_errorEsData_key = 'send_email_errorEsData';
    public $openEmailNotice = true;
    /*
     * *****创建各个表的索引*****
     *
     * 作为脚本使用
     * 只创建一次
     *
     * 商品索引 goods
     * 定制索引 trip
     * 产品索引 product
     * POI索引 poi
     * FAQ索引 faq
     * 城市索引 city
     * 供应商索引 supplier
     * 订单索引 order
     * */
    public function createIndex(){
        $EsapiModel = new EsapiModel();
        $indexArr = $this->indexArr;
        foreach ($indexArr as $k=>$v) {
            //如果存在则清空索引
            $EsapiModel->getIndex($v) && $EsapiModel->delete_index($v);//先清空索引
        }
    }

    //刷新ES的标品数据
    public function refreshStandardDataToES($standard_id=0)
    {
        //获取数据 存入es
        return $this->addStandardDoc($standard_id);//添加数据
    }

    //刷新ES的标品数据
    public function initStandardDoc($standard_id=0)
    {
        $EsapiModel = new EsapiModel();
        //如果存在则清空索引
        $EsapiModel->getIndex($this->indexArr[5]) && $EsapiModel->delete_index($this->indexArr[5]);//先清空索引
        //获取数据 存入es
        return $this->addStandardDoc($standard_id);//添加数据
    }

    //创建映射模板  在createIndex方法中调用
    public function createMap($index){
        $EsapiModel = new EsapiModel();
        $mapConfig = [//名称
            'type' => 'string', // 字符串型
            'index' => 'analyzed', // 全文搜索
            'analyzer' => 'ik_smart',
        ];
        $properties = [
            'id' => [//ID
                'type' => 'string', // 字符串型
                'index' => 'not_analyzed',
            ],
            'name' => $mapConfig, //名称
            'content' => $mapConfig, //内容
        ];
        switch ($index){
            case $this->indexArr[0]:
                $properties['goods_id'] = $mapConfig;//goods_id
                $properties['code'] = $mapConfig;//code
                $properties['city'] = $mapConfig;//城市
                break;
            case $this->indexArr[2]:
                $properties['item_num'] = $mapConfig;//产品编号
                $properties['supplier_item_code'] = $mapConfig;//供应商产品编号
                $properties['supplier'] = $mapConfig;//供应商
                break;
            case $this->indexArr[3]:
                $properties['city'] = $mapConfig;//城市
                $properties['ticket'] = $mapConfig;//门票
                break;
            case $this->indexArr[4]:
                $properties['groupid'] = $mapConfig;//groupid
                $properties['typeid'] = [//typeid
                    'type' => 'integer', // 整型
                    'index' => 'not_analyzed',
                ];
                break;
            case $this->indexArr[5]:
                $properties['standardId'] = [//typeid
                    'type' => 'integer', // 整型
                    'index' => 'not_analyzed',
                ];
                break;
            default:
                break;
        }
        $EsapiModel->create_mappings($index,$properties);
    }

    //各个索引分别插入文档
    //插入goods数据
    public function addGoodsDoc(){
        ignore_user_abort();//关闭浏览器仍然执行
        set_time_limit(0);//让程序一直执行下去
        $EsapiModel = new EsapiModel();
        $goods = db("goods")
            ->alias("g")
            ->join("city c","g.city_id=c.id","LEFT")
            ->field("g.goods_id,g.goods_name,g.code,c.name as cname,c.eng_name")
            ->select();
        foreach ($goods as $k=>$v) {
            $goodsDocData = [
                'id'=>$v['goods_id'],
                'goods_id'=>$v['goods_id'],
                'name'=>$v['goods_name'],
                'content'=>'',
                'code'=>$v['code'],
                'city'=>!empty($v['eng_name']) ? $v['cname']."_".$v['eng_name'] : $v['cname'],
            ];
            if($EsapiModel->exists_doc($v['goods_id'],$this->indexArr[0])==true){//已存在时update
                $EsapiModel->update_doc($v['goods_id'],$goodsDocData,$this->indexArr[0]);
            }else{//不存在时add
                $EsapiModel->add_doc($v['goods_id'],$goodsDocData,$this->indexArr[0]);
            }
        }
        var_dump("插入goods成功");
    }
    //插入trip数据
    public function addTripDoc(){
        ignore_user_abort();//关闭浏览器仍然执行
        set_time_limit(0);//让程序一直执行下去
        $EsapiModel = new EsapiModel();
        $trip = db("trip")->field("id,name")->select();
        foreach ($trip as $k=>$v) {
            $tripDocData = [
                'id'=>$v['id'],
                'name'=>$v['name'],
                'content'=>'',
            ];
            if($EsapiModel->exists_doc($v['id'],$this->indexArr[1])==true){//已存在时update
                $EsapiModel->update_doc($v['id'],$tripDocData,$this->indexArr[1]);
            }else{//不存在时add
                $EsapiModel->add_doc($v['id'],$tripDocData,$this->indexArr[1]);
            }
        }
        var_dump("插入trip成功");
    }
    //插入product数据
    public function addProductDoc(){
        ignore_user_abort();//关闭浏览器仍然执行
        set_time_limit(0);//让程序一直执行下去
        //供应商   不能放上面，引入类构造方法会过滤html标签
        $KbxOther = new KbxOtherController();
        $supplierArr = $KbxOther->kbx_suppliers_list();
        $supplierNameArr = array();
        foreach ($supplierArr as $k=>$v) {
            $supplierNameArr[$v['id']] = $v['name']??'unknown';
        }

        $EsapiModel = new EsapiModel();
        $product = db("product")->field("id,name,item_num,supplier_item_code,supplier_id")->select();
        foreach ($product as $k=>$v) {
            if(!empty($v['supplier_id']) && $v['supplier_id']!==''){
                $supplier = !empty($supplierNameArr[$v['supplier_id']]) ? $supplierNameArr[$v['supplier_id']] : '';
            }else{
                $supplier = '';
            }
            $productDocData = [
                'id'=>$v['id'],
                'name'=>$v['name'],
                'content'=>'',
                'item_num'=>$v['item_num'],
                'supplier_item_code'=>$v['supplier_item_code'],
                'supplier'=>$supplier,
            ];

            if($EsapiModel->exists_doc($v['id'],$this->indexArr[2])==true){//已存在时update
                $EsapiModel->update_doc($v['id'],$productDocData,$this->indexArr[2]);
            }else{//不存在时add
                $EsapiModel->add_doc($v['id'],$productDocData,$this->indexArr[2]);
            }
        }
        var_dump("插入product成功");
    }
    //插入poi数据
    public function addPoiDoc(){
        ignore_user_abort();//关闭浏览器仍然执行
        set_time_limit(0);//让程序一直执行下去
        $EsapiModel = new EsapiModel();
        $poi = db("poi")
            ->alias("p")
            ->join("city c","p.groupid=c.id","LEFT")
            ->where("p.deleted",0)
            ->field("p.id,p.name,p.eng_name,p.ticket_cost,c.name as cname,c.eng_name as cename")
            ->select();
        foreach ($poi as $k=>$v) {
            $poiDocData = [
                'id'=>$v['id'],
                'name'=>!empty($v['eng_name']) ? $v['name']."_".$v['eng_name'] : $v['name'],
                'content'=>'',
                'city'=>!empty($v['cename']) ? $v['cname']."_".$v['cename'] : $v['cname'],
                'ticket'=>$v['ticket_cost'],
            ];
            if($EsapiModel->exists_doc($v['id'],$this->indexArr[3])==true){//已存在时update
                $EsapiModel->update_doc($v['id'],$poiDocData,$this->indexArr[3]);
            }else{//不存在时add
                $EsapiModel->add_doc($v['id'],$poiDocData,$this->indexArr[3]);
            }
        }
        var_dump("插入poi成功");
    }
    //插入faq数据
    public function addFaqDoc(){
        ignore_user_abort();//关闭浏览器仍然执行
        set_time_limit(0);//让程序一直执行下去

        $EsapiModel = new EsapiModel();
        $typeIdArr = [
            1=>'产品',
            3=>'Viator商品',
            4=>'供应商',
            5=>'城市',
            6=>'销售话术',
            7=>'新人培训',
            8=>'定制行程方案',
        ];
        foreach ($typeIdArr as $typeid=>$typeName) {
            $where = [];
            $where['deleted'] = 0;
            $query = db("faq")
                ->where($where)
                ->field("count(id) as counts,groupid")
                ->group("groupid")
                ->select(false);

            $info = [];
            $info_where = [];
            if($typeid==1){//产品
                $info = db("product t")
                    ->join("(".$query.") as q","t.id=q.groupid")
                    ->where($info_where)
                    ->field("t.id,t.name")
                    ->select();
            }elseif($typeid==3){//Viator商品
                $info = db("goods g")
                    ->join("(".$query.") as q","g.goods_id=q.groupid")
                    ->where($info_where)
                    ->field("g.goods_id as id,g.goods_name as name")
                    ->select();
            }elseif($typeid==4) {//供应商
                $KbxOther = new KbxOther();
                $supplierArr = $KbxOther->kbx_suppliers_list();
                foreach ($supplierArr as $k=>$v) {
                    if(!empty($v['id'])){
                        $info[] = [
                            'id'=>$v['id'],
                            'name'=>$v['name']??'unknown',
                        ];
                    }
                }
            }elseif($typeid==5) {//城市
                $info = db("city")
                    ->where("type","CITY")
                    ->where("deleted","0")
                    ->field("id,name")
                    ->select();
            }elseif($typeid==6 || $typeid==7) {//6销售话术  7新人培训
                $info_where['typeid'] = $typeid;
                $info_where['deleted'] = 0;
                $info = db("faqtitle")
                    ->where($info_where)
                    ->field("id,title as name")
                    ->select();
            }

            foreach ($info as $k=>$v) {
                $faqData = db("faq")->where("groupid",$v['id'])->field("title,content")->select();
                $faq_content = '';
                if(!empty($faqData)){
                    foreach ($faqData as $f_v) {
                        if(!empty($f_v['title'])){
                            $faq_content .= "<h3>".$f_v['title']."</h3>";
                        }
                        if(!empty($f_v['content']) && $f_v['content']!==''){
                            $faq_content .= $f_v['content']."<br>";
                        }
                    }
                    $esFaqData = [];
                    $groupid = $v['id'];
                    $faqid = $typeid."000".$groupid;
                    $esFaqData['id'] = $faqid;
                    $esFaqData['groupid'] = (string)$groupid;
                    $esFaqData['name'] = $v['name'];
                    $esFaqData['typeid'] = $typeid;
                    $esFaqData['typename'] = $typeName;
                    $esFaqData['content'] = $faq_content;

                    if($EsapiModel->exists_doc($faqid,$this->indexArr[4])==true){//已存在时update
                        $EsapiModel->update_doc($faqid,$esFaqData,$this->indexArr[4]);
                    }else{//不存在时add
                        $EsapiModel->add_doc($faqid,$esFaqData,$this->indexArr[4]);
                    }
                }else{
                    unset($info[$k]);
                    continue;
                }
            }
        }

        var_dump("插入faq成功");
    }
    //插入标品数据
    public function addStandardDoc($standard_id=0){
        ignore_user_abort();//关闭浏览器仍然执行
        set_time_limit(0);//让程序一直执行下去
        $EsapiModel = new EsapiModel();
        $standardModel = new Standard();
        $index_name = $this->indexArr[5];
        $from = 'toB';
        $where['s.status'] = 1;//启用的标品
        $where['s.is_deleted'] = 0;//未删除的标品
        $where['s.show_toB'] = 1;//用于toB的标品
        $where['s.allow_everyone_quote'] = 1;//用于 是否为通用产品的标识
//        $where['topCate'] = ['in',[1,2]];
        if(!empty($standard_id)) $where['s.id'] = $standard_id;//刷新单条数据
        $list = db("standard s")
            ->where($where)
            ->join("goods g",'g.goods_id=s.goods_id','left')
            ->join("standardtrip st",'st.sid=s.id','left')
            ->join("city c",'c.id=st.startCityId','left')
            ->field('s.id as standardId,s.name as standardName,s.type as standardType,introduce as subTitle,showImg,g.goods_id,g.goods_name,is_recommend,s.sortNum,s.introduce,
            trip_id,startCityId,c.name as startCityName,c.kbx_id as kbxStartCityId,days,endDays,subType,toursLineTitle,specialInfo,topCate')
            ->order("s.is_recommend desc,sortNum desc,s.id desc")
//            ->page(1,10)
            ->select();
//        var_dump($list);exit;
//        var_dump(db()->getLastSql());exit;
        if(empty($list)){
            $this->recordStandardEsLog('暂无数据更新！！！');
            return json_encode(['code'=>200,'msg'=>'success']);
        }
        foreach ($list as $key=>$value){
            $list[$key]['id'] = $value['standardId'];
            $list[$key]['standardTypeName'] = $standardModel->getTypeName($value['standardType']);
            $list[$key]['standardTags'] = $standardModel->getStandardTags($value['standardId']);
            $list[$key]['subType'] = $standardModel->getSubType($value['subType']);

            //获取关联的商品信息
            $list[$key]['goodsInfo'] = [];
            $list[$key]['showImg'] = "";
            if(!empty($value['goods_id'])){
                $list[$key]['goodsInfo'] = $standardModel->getLinkGoodsInfo($value['goods_id'],$value['standardId'],$from);
                $image = $list[$key]['goodsInfo']['small_image']??[];
                $list[$key]['showImg'] = $standardModel->checkImgUrl($image[0]??"")??"";
                $list[$key]['goodsprice'] = floatval($list[$key]['goodsInfo']['goodsprice'])??0;
                $list[$key]['salesVolume'] = $list[$key]['goodsInfo']['goodssales']??"0";
                unset($list[$key]['goodsInfo']['small_image']);
                $list[$key]['startCityId'] = $value['startCityId']?:$list[$key]['goodsInfo']['city_id'];
                $list[$key]['startCityName'] = $value['startCityName']?:$list[$key]['goodsInfo']['cityName'];
                $list[$key]['kbxStartCityId'] = $value['kbxStartCityId']?:$list[$key]['goodsInfo']['kbxCityId'];
                $list[$key]['tags'] = !empty($list[$key]['goodsInfo']['tags'])?
                    array_merge($list[$key]['standardTags'],$list[$key]['goodsInfo']['tags']):
                    $list[$key]['standardTags'];
            }
        }
        //导入数据
        $this->recordStandardEsLog('开始更新数据');
        foreach ($list as $k=>$v){
            if($EsapiModel->exists_doc($v['standardId'],$index_name)==true){//已存在时update
                $EsapiModel->update_doc($v['standardId'],$v,$index_name);
                $this->recordStandardEsLog('更新【'.$v['standardId'].'】的数据成功');
            }else{//不存在时add
                $EsapiModel->add_doc($v['standardId'],$v,$index_name);
                $this->recordStandardEsLog('插入【'.$v['standardId'].'】的数据成功');
            }
        }
        $this->recordStandardEsLog('更新数据结束');
        return json_encode(['code'=>200,'msg'=>'success']);
    }
    //删除标品数据
    public function delStandardDoc($standard_id=0){
        if(empty($standard_id)){
            $this->recordStandardEsLog('删除数据失败，原因是standard_id为空');
            return json_encode(['code'=>-1,'msg'=>'fail']);
        }
        $EsapiModel = new EsapiModel();
        $index_name = $this->indexArr[5];
        //先检查是否存在
        if($EsapiModel->exists_doc($standard_id,$index_name)==true){
            $EsapiModel->delete_doc($standard_id,$index_name,$index_name.'_type');
            $this->recordStandardEsLog('删除id为【'.$standard_id.'】的数据成功');
        }
        return json_encode(['code'=>200,'msg'=>'success']);
    }
    //日志记录
    public function recordStandardEsLog($content)
    {
        file_put_contents(APP_PATH.'/logs/standard_es_log_'.date('Ym'),date('m-d H:i:s').$content."\n",FILE_APPEND);
    }
    //执行查询
    public function esSearch($keywords){
        ignore_user_abort();//关闭浏览器仍然执行
        set_time_limit(0);//让程序一直执行下去
        $EsapiModel = new EsapiModel();
        $indexArr = $this->indexArr;
        $resultData = [];
        foreach ($indexArr as $k=>$v) {
            $size = 100;
            if($v==$this->indexArr[0]){
                $size = 50;
                $matchArr = [
                    [ 'match' => [ 'content' => $keywords]],
                    [ 'match' => [ 'name' => $keywords]],
                    [ 'match' => [ 'code' => $keywords]],
                    [ 'match' => [ 'city' => $keywords]],
                ];
                $highlightArr = [
                    "content" => new \stdClass(),
                    "name" => new \stdClass(),
                    "code" => new \stdClass(),
                    "city" => new \stdClass(),
                ];
            }elseif($v==$this->indexArr[2]){
                $matchArr = [
                    [ 'match' => [ 'content' => $keywords]],
                    [ 'match' => [ 'name' => $keywords]],
                    [ 'match' => [ 'item_num' => $keywords]],
                    [ 'match' => [ 'supplier_item_code' => $keywords]],
                    [ 'match' => [ 'supplier' => $keywords]],
                ];
                $highlightArr = [
                    "content" => new \stdClass(),
                    "name" => new \stdClass(),
                    "item_num" => new \stdClass(),
                    "supplier_item_code" => new \stdClass(),
                    "supplier" => new \stdClass(),
                ];
            }elseif($v==$this->indexArr[3]){
                $matchArr = [
                    [ 'match' => [ 'content' => $keywords]],
                    [ 'match' => [ 'name' => $keywords]],
                    [ 'match' => [ 'ticket' => $keywords]],
                    [ 'match' => [ 'city' => $keywords]],
                ];
                $highlightArr = [
                    "content" => new \stdClass(),
                    "name" => new \stdClass(),
                    "ticket" => new \stdClass(),
                    "city" => new \stdClass(),
                ];
            }else{
                $matchArr = [
                    [ 'match' => [ 'content' => $keywords]],
                    [ 'match' => [ 'name' => $keywords]]
                ];
                $highlightArr = [
                    "content" => new \stdClass(),
                    "name" => new \stdClass(),
                ];
            }

            $matchResArr = $EsapiModel->search_doc($v,$matchArr,$highlightArr,0,$size);
            $hitsArr = [];
            if(!empty($matchResArr['hits'])){
                if(!empty($matchResArr['hits']['hits'])){
                    $hitsArr = $matchResArr['hits']['hits'];
                    foreach ($hitsArr as $k_hit=>$v_hit) {
                        if(empty($v_hit['_score'])){
                            $hitsArr[$k_hit]['_score'] = 0;
                        }
                    }
                    $scoreArr = array_column($hitsArr,'_score');//按照得分排序
                    array_multisort($scoreArr,SORT_DESC,$hitsArr);
                }
            }
            foreach ($hitsArr as $k_hit=>$v_hit) {
                $v_hit['_source']['score'] = $v_hit['_score'];
                if(!empty($v_hit['_source'])){
                    $hitsArr[$k_hit] = [
                        'source'=>$v_hit['_source'],
                        'light'=>$v_hit['highlight'],
                    ];
                }else{
                    $hitsArr[$k_hit] = [];
                }
            }
            $resultData[$v] = $hitsArr;
        }

        return $resultData;
    }
    //只获取城市
    public function esStandardCitySearch($search_arr){
        $EsapiModel = new EsapiModel();
        $index_name = $this->indexArr[5];
        //构造搜索条件
        $matchArr = new \ArrayObject();
        if(!empty($search_arr['keyword'])){
            $keyword_match = [
                ['match'=>['standardName'=>$search_arr['keyword']]],
                ['match'=>['goods_name'=>$search_arr['keyword']]],
                ['match'=>['introduce'=>$search_arr['keyword']]],
                ['match'=>['goodsInfo.goods_ename'=>$search_arr['keyword']]],
            ];
            $matchArr['bool']['must'][] = ['bool'=>['should'=>$keyword_match]];
        }

        //高亮显示
        $highlightArr = [];
        $sortArr = [];
        //热卖排序
        if(!empty($search_arr['is_recommend'])){
            $sortArr["is_recommend"] = ['order'=>'desc'];
        }
        //金额排序
        if(!empty($search_arr['sort_price']) && in_array($search_arr['sort_price'],['asc','desc'])){
            $sortArr["goodsprice"] = ['order'=>$search_arr['sort_price']];
        }

        $matchResArr = $EsapiModel->multi_param_search_doc($index_name,$matchArr,$sortArr,
            ['startCityId','startCityName','kbxStartCityId'],$highlightArr);
        $hitsArr = $resultData = $cityIds = [];
        if(!empty($matchResArr['hits'])){
            if(!empty($matchResArr['hits']['hits'])){
                $hitsArr = $matchResArr['hits']['hits'];
                foreach ($hitsArr as $key=>$value){
                    if(!empty($value['_source']['startCityId'])
                        && !in_array($value['_source']['startCityId'],$cityIds)){
                        $resultData[] = $value['_source'];
                        $cityIds[] = $value['_source']['startCityId'];
                    }
                }
            }
        }
//        高亮显示
//        foreach ($hitsArr as $k_hit=>$v_hit) {
//            $v_hit['_source']['score'] = $v_hit['_score'];
//            if(!empty($v_hit['_source'])){
//                $hitsArr[$k_hit] = [
//                    'source'=>$v_hit['_source'],
//                    'light'=>$v_hit['highlight'],
//                ];
//            }else{
//                $hitsArr[$k_hit] = [];
//            }
//        }

        return $resultData;
    }
    //执行standard查询
    // 条件检索包含关键字 城市 标签
    // 完整匹配
    // fromCityId=X and
    // (standardName like '%K%' or standardName like '%K%' or standardName like '%K%') and
    // (tags.tag_id=M or tags.tag_id=N )
    public function esStandardSearch($search_arr,$page,$size){
        $EsapiModel = new EsapiModel();
        $index_name = $this->indexArr[5];
        $from = ($page-1)*$size;
        //构造搜索条件
        $matchArr = new \ArrayObject();
        if(!empty($search_arr['keyword'])){
            $keyword_match = [
                ['match'=>['standardName'=>$search_arr['keyword']]],
                ['match'=>['goods_name'=>$search_arr['keyword']]],
                ['match'=>['introduce'=>$search_arr['keyword']]],
                ['match'=>['goodsInfo.goods_ename'=>$search_arr['keyword']]],
            ];
            $matchArr['bool']['must'][] = ['bool'=>['should'=>$keyword_match]];
        }
        //城市筛选
        if(!empty($search_arr['fromCityId'])){
            $city_ids = explode(",",$search_arr['fromCityId']);
            foreach ($city_ids as $city_value){
                $city_match[] = ['match'=>['startCityId'=>$city_value]];
            }
            $matchArr['bool']['must'][] = ['bool'=>['should'=>$city_match]];
        }
        //并集标签筛选
        if(!empty($search_arr['shouldTags'])){
            $s_tags = explode(",",$search_arr['shouldTags']);
            foreach ($s_tags as $tag_value){
                $s_tags_match[] = ['match'=>['standardTags.tagId'=>$tag_value]];
            }
            $matchArr['bool']['must'][] = ['bool'=>['should'=>$s_tags_match]];
        }
        //交集标签筛选
        if(!empty($search_arr['mustTags'])){
            $m_tags = explode(",",$search_arr['mustTags']);
            foreach ($m_tags as $tag_value){
                $m_tags_match[] = ['match'=>['goodsInfo.tags.tag_id'=>$tag_value]];
            }
            $matchArr['bool']['must'][] = $m_tags_match;
        }
        //高亮显示
        $highlightArr = [];
        $sortArr = [];
        //热卖排序
        if(!empty($search_arr['is_recommend'])){
            $matchArr['bool']['must'][] = ['match'=>['is_recommend'=>1]];
            $sortArr["standardId"] = ['order'=>'desc'];
            $sortArr["sortNum"] = ['order'=>'desc'];
        }
        //金额排序
        if(!empty($search_arr['sort_price']) && in_array($search_arr['sort_price'],['asc','desc'])){
            $sortArr["goodsprice"] = ['order'=>$search_arr['sort_price']];
        }

        $matchResArr = $EsapiModel->multi_param_search_doc($index_name,$matchArr,$sortArr,[],$highlightArr,$from,$size);
        $hitsArr = $resultData = [];
        $total = 0;
        if(!empty($matchResArr['hits'])){
            $total = $matchResArr['hits']['total']??0;
            if(!empty($matchResArr['hits']['hits'])){
                $hitsArr = $matchResArr['hits']['hits'];
                foreach ($hitsArr as $key=>$value){
                    $resultData[] = $value['_source'];
                }
            }
        }


//        高亮显示
//        foreach ($hitsArr as $k_hit=>$v_hit) {
//            $v_hit['_source']['score'] = $v_hit['_score'];
//            if(!empty($v_hit['_source'])){
//                $hitsArr[$k_hit] = [
//                    'source'=>$v_hit['_source'],
//                    'light'=>$v_hit['highlight'],
//                ];
//            }else{
//                $hitsArr[$k_hit] = [];
//            }
//        }

        return [$total,$resultData];
    }

    //更新es数据  脚本
    public function addEsData(){
        ignore_user_abort();//关闭浏览器仍然执行
        set_time_limit(0);//让程序一直执行下去

        $this->createIndex();
//        var_dump("更新完成");exit;
        $this->addGoodsDoc();
        $this->addTripDoc();
        $this->addProductDoc();
        $this->addPoiDoc();
        $this->addFaqDoc();
        $this->initStandardDoc();

        var_dump("更新完成");
    }

    //插入特定类型的數據
    public function insertOneDocByName($name=''){
        if(empty($name) || !in_array($name,$this->indexArr)) return json_encode(['code'=>-1,'msg'=>'类型错误，请填写'.implode(',',$this->indexArr)]);
        ignore_user_abort();//关闭浏览器仍然执行
        set_time_limit(0);//让程序一直执行下去
        switch ($name){
            case $this->indexArr[0]:
                $this->addGoodsDoc();
                break;
            case $this->indexArr[1]:
                $this->addTripDoc();
                break;
            case $this->indexArr[2]:
                $this->addProductDoc();
                break;
            case $this->indexArr[3]:
                $this->addPoiDoc();
                break;
            case $this->indexArr[4]:
                $this->addFaqDoc();
                break;
            default:
                break;
        }
        return json_encode(['code'=>200,'msg'=>'更新'.$name.'完成']);
    }
    //删除特定类型的數據
    public function delOneDocByName($name="")
    {
        $EsapiModel = new EsapiModel();
        if(empty($name) || !in_array($name,$this->indexArr)) return json_encode(['code'=>-1,'msg'=>'类型错误，请填写'.implode(',',$this->indexArr)]);
        $EsapiModel->delete_index($name);
        return json_encode(['code'=>200,'msg'=>"删除索引为【{$name}】的文档成功！\n"]);
    }
    //清空所有的文档 仅测试站使用
    public function delAllDoc()
    {
        $EsapiModel = new EsapiModel();
        $url = $this->api_url."/_cat/indices?format=json";
        $data = (new Common())::http($url);
        if(!empty($data)){
            $data = json_decode($data,true);
            foreach ($data as $value){
                $EsapiModel->delete_index($value['index']);
                echo "删除索引为【{$value['index']}】的文档成功！\n";
            }
        }else{
            echo "暂无文档！";
        }

    }

    //报警机制
    public function noticeEsDataError()
    {
        //邮件收件人
        $address = 'david@kuaibangxing.com';
        $url = $this->api_url."/_cat/indices?format=json";
        $data = (new Common())::http($url);

        if(!empty($data)){
            $data = json_decode($data,true);
            //判断数据是否符合标准
            $index_arr = array_merge($this->indexArr,$this->otherIndexArr);
//            var_dump($index_arr);exit;
            $no_exist_index = [];
            $cahce_msg = Cache::get($this->send_email_errorEsData_key);
            if(!$this->openEmailNotice){
                trace('ES预警机制邮件已关闭！');
                return $this->result('ES预警机制邮件已关闭',[],40404,'json');
            }
            if(!empty($cahce_msg)){
                trace('ES预警机制邮件已发送，当天有效！');
                return $this->result('ES预警机制邮件无需发送多次',[],40405,'json');
            }
            //触发数量预警
            if(count($data) != 12){
                $this->setCacheExpiredTime('Index Number Error');
                $subject = 'ES数据库索引数量预警';
                $content = 'ES数据库数据索引为'.implode(',',array_column($data,'index'));
                (new Common())->sendNoticeMailToKbx($subject,$address,$content);
                return $this->result('ES数据库索引数量预警',[],40401,'json');
            }else{
                foreach ($data as $k=>$v){
                    if(!in_array($v['index'],$index_arr)){
                        //触发索引预警
                        $no_exist_index[] = $v['index'];
                    }
                }
                if(!empty($no_exist_index)){
                    $this->setCacheExpiredTime('No Index Error');
                    $subject = 'ES数据库索引错误预警';
                    $content = 'ES数据库数据多余索引为'.implode(',',$no_exist_index);
                    (new Common())->sendNoticeMailToKbx($subject,$address,$content);
                    return $this->result('ES数据库索引数量预警',[],40402,'json');
                }
                return $this->result('no Error',[],200,'json');
            }
        }else{
            $this->setCacheExpiredTime('No Data Error');
            $subject = 'ES数据库索引为空';
            $content = 'ES数据库数据为空';
            (new Common())->sendNoticeMailToKbx($subject,$address,$content);
            return $this->result('no Data',[],40403,'json');
        }
    }

    //设置过期时间
    public function setCacheExpiredTime($value){
        $key = $this->send_email_errorEsData_key;
        Cache::set($key,$value,new \DateTime(date('Y-m-d H:i:s',strtotime('+2 hours'))));
//        Cache::set($key,$value,new \DateTime(date('Y-m-d H:i:s',strtotime('+120 seconds'))));
    }

    //删除过期时间
    public function delCacheExpiredTime(){
        $key = $this->send_email_errorEsData_key;
        Cache::get($key) && Cache::rm($key);
    }

    //仅测试站使用
    public function getAllIndex()
    {
        $url = $this->api_url."/_cat/indices?format=json";
        $data = (new Common())::http($url);
        if(!empty($data)){
            $data = json_decode($data,true);
            foreach ($data as $value){
                echo implode(' ',$value);
                echo "\r\n";
            }
        }else{
            echo "暂无文档！";
        }
    }

}